#include <io.h>
#include <fcntl.h>

#include "gol1.h"

#include "dx.h"
#include "shd.h"

#pragma warning(disable:4996)	// sprintf is unsafe

const char g_szClassName[] = "WindowClass";

LARGE_INTEGER nFreq;
LARGE_INTEGER nCount;

int nNumFrames = 0;
float fAvgFPS = 0.0f;


LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int nPrevXMouse = 0;
	static int nPrevYMouse = 0;
	int nXDiff, nYDiff;

	char msglog[64] = "";
	int nWParam;
	int nHiWord;

    HDC hdc;
    PAINTSTRUCT ps ;
    RECT        rect ;



    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hWnd);
        break;
        case WM_DESTROY:
			AppDone( hWnd );
            PostQuitMessage(0);
			return 0;
        break;
		case WM_MOUSEWHEEL:
			nWParam = wParam;
			nHiWord = ( nWParam & 0xffff0000 ) >> 16;
			sprintf( msglog, "wheel: %d\n", nHiWord );
			trace( msglog );
			return 0;
		break;
		case WM_LBUTTONUP:
		case WM_LBUTTONDOWN:
			//nXDiff = 0;
			//nYDiff = 0;
			nPrevYMouse = LOWORD(lParam);
			nPrevXMouse = HIWORD(lParam);
			return 0;
		break;
		case WM_MOUSEMOVE:
			nXDiff = -HIWORD(lParam) + nPrevXMouse;
			nPrevXMouse = HIWORD(lParam);

			nYDiff = LOWORD(lParam) - nPrevYMouse;
			nPrevYMouse = LOWORD(lParam);

			if( wParam & MK_LBUTTON )       // rot
			{
				fXAngle += (float)nXDiff;
				fYAngle -= (float)nYDiff;
				sprintf( msglog, "fXAngle : %f fYAngle : %f\n", fXAngle, fYAngle );
//				trace( msglog );				
			}
            

			if( wParam & MK_MBUTTON )       // pan
			{
				//fXOffs -= (float)nYDiff*0.1f;
				//fYOffs -= (float)nXDiff*0.1f;
				fXOffs = (float)-nYDiff;
				fYOffs = (float)-nXDiff;
				sprintf( msglog, "fXOffs : %f fYOffs : %f\n", fXOffs, fYOffs );
//				trace( msglog );				
			}

            if( wParam & MK_RBUTTON )       // zoom
            {
                fZOffs = (float)-nXDiff;
            }
			return 0;
			break;

		case WM_PAINT:
            hdc = BeginPaint (hWnd, &ps) ;          
            GetClientRect (hWnd, &rect) ;
            DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint (hWnd, &ps) ;
//            return DefWindowProc(hWnd, msg, wParam, lParam);
            return 0;
		break;
		//case WM_NCPAINT:
  //          hdc = GetDCEx( hWnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
  //          Rectangle( hdc, 0, 0, 1000, 1000 );
  //          ReleaseDC(hWnd, hdc);
  //          return 0 ;
		//break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}

WNDCLASSEX wc;
HWND hwnd;

int WindowsInit( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_CLASSDC;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = NULL;
    wc.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = NULL;

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "Fereastra",
        WS_OVERLAPPED,
        CW_USEDEFAULT, CW_USEDEFAULT, 1000, 1000,
        GetDesktopWindow(), NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    return (int)hwnd;
}



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;

    //Step 1: Registering the Window Class


	OpenConsole();

	QueryPerformanceFrequency( &nFreq );
	QueryPerformanceCounter( &nCount );

    if( !WindowsInit( hInstance, hPrevInstance, lpCmdLine, nCmdShow ) )
        return 0;

#ifdef __GRAPH
	DXInit( hwnd );
#endif

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

	

    // Step 3: The Message Loop


	ZeroMemory( &msg, sizeof(msg) );
    while( msg.message!=WM_QUIT )
    {
        if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
            Loop(hwnd);
    }


	UnregisterClass( g_szClassName, wc.hInstance );

	return 0;
}

void AppDone(HWND hWnd)
{
	Done(hWnd);
#ifdef _DEBUG
	FreeConsole( );
#endif //_DEBUG
}


void con_trace( const char* s)
{
	OutputDebugString( s );
	printf( s );
}

void OpenConsole( void )
{
#ifdef _DEBUG
	//if(FALSE)
	if(TRUE)
	{
		HANDLE handle;
		int hCrt;
		FILE *hf;
		AllocConsole( );
		handle = GetStdHandle( STD_OUTPUT_HANDLE );
		hCrt = _open_osfhandle(
								(intptr_t)handle,
								_O_TEXT);	// return a runtime file handle
		hf = _fdopen( hCrt, "w" );					// stream
		*stdout = *hf;
	}
#endif //_DEBUG
}
